home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / c / pcl4c40.zip / AMODEM.C next >
Text File  |  1993-09-22  |  10KB  |  290 lines

  1. /*
  2. **  ASCII text file transfer using XON / OFF flow control protocol.
  3. **  Transfer ASCII files only. Do not attempt to transfer binary files.
  4. */
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <fcntl.h>
  9. #include <string.h>
  10. #include <io.h>
  11. #include <sys\types.h>
  12. #include <sys\stat.h>
  13.  
  14. #include "pcl4c.h"
  15. #include "ascii.h"
  16. #include "term_io.h"
  17. #include "xymodem.h"
  18. #include "amodem.h"
  19. #include "term.h"
  20.  
  21. #define FALSE 0
  22. #define TRUE !FALSE
  23.  
  24. #define ONE_SECOND 18
  25.  
  26. char lastXchar;     /* last XON or XOFF sent */
  27.  
  28. int TxAscii(
  29.   int Port,            /* COM port [0..3] */
  30.   char Filename[],     /* filename buffer */
  31.   char Buffer[],       /* data buffer */
  32.   int Length,          /* size of Buffer */
  33.   int SyncFlag,        /* synchronize with XON 1st */
  34.   int CharPace,        /* millisecond delay after sending each character */
  35.   int TermChar,        /* termination character (0x00 ==> none) */
  36.   int EchoFlag)        /* do local echo if TRUE */
  37. {int i;
  38.  int Code;           /* return code */
  39.  int Handle;         /* file Handle */
  40.  char LastChar;      /* last character sent */
  41.  int TxChars = 0;    /* # characters transmitted */
  42.  int Count;          /* # bytes read from disk */
  43.  char Temp[81];      /* temporary buffer */
  44.  /* begin */
  45.  Handle = open(Filename,O_RDONLY|O_BINARY,S_IREAD);
  46.  if(Handle<0)
  47.      {strcpy(Temp,"Cannot open ");
  48.       strcat(Temp,Filename);
  49.       DisplayLine(Temp,NULL,0);
  50.       return(FALSE);
  51.      }
  52.  /* do we wait for XON before starting ? */
  53.  if(SyncFlag)
  54.    {/* wait for incoming XON */
  55.     DisplayLine("ASCII: Waiting for XON",NULL,0);
  56.     while(1)
  57.        {if(SioBrkKey())
  58.           {DisplayLine("Canceled by USER",NULL,0);
  59.            return(FALSE);
  60.           }
  61.         Code = SioGetc(Port,ONE_SECOND);
  62.         if(Code==-1) continue;
  63.         if(Code<0) return(FALSE);
  64.         if((char)Code==XON)
  65.            {DisplayLine("ASCII: initial XON received",NULL,0);
  66.             /* slight delay */
  67.             SioDelay(ONE_SECOND/2);
  68.             break;
  69.            }
  70.         /* received character not XON */
  71.         MyCrtWrite((char)Code);
  72.        }
  73.    }
  74.  /* begin transfer */
  75.  lastXchar =  XON;
  76.  DisplayLine("ASCII: Starting send",NULL,0);
  77.  while(SioKeyPress()) SioKeyRead();
  78.  /* clear comm port */
  79.  SioRxFlush(Port);
  80.  /* send ascii file ( stop at ^Z ) */
  81.  while(1)
  82.      {/* read next buffer from disk */
  83.       Count = read(Handle,Buffer,Length);
  84.       if(Count==0) break;
  85.       if(Count<0)
  86.           {SayError(Port,"Error on disk read");
  87.            return(FALSE);
  88.           }
  89.       /* send one byte at a time */
  90.       for(i=0;i<Count;i++)
  91.           {/* User ABORTS ? */
  92.            if(UserAborts(Port)) return(FALSE);
  93.            /* send byte */
  94.            LastChar = Buffer[i];
  95.            if(EchoFlag) MyCrtWrite(LastChar);
  96.            /* send the character */
  97.            PutChar(Port,LastChar);
  98.            if(CharPace>0) SioDelay(CharPace);
  99.            /* slight delay after each line */
  100.            if(LastChar==LF) SioDelay(4*(CharPace+1));
  101.            TxChars++;
  102.            /* ^Z marks the end of a text file */
  103.            if(LastChar==CTLZ) break;
  104.            /* check for incoming XON */
  105.            if(lastXchar==XON)
  106.                 {/* check for incoming XON / XOFF */
  107.                  Code = GetChar(Port,0);
  108.                  if(Code>0)
  109.                     {/* is byte a XOFF ? */
  110.                      if((char)Code==XOFF)
  111.                          {/* wait for XON */
  112.                           DisplayLine("XOFF received",NULL,0);
  113.                           lastXchar = XOFF;
  114.                           /* wait for XON */
  115.                           while(1)
  116.                               {/* user want to quit ? */
  117.                                if(SioBrkKey())
  118.                                    {DisplayLine("Canceled by USER",NULL,0);
  119.                                     return(FALSE);
  120.                                    }
  121.                                Code = GetChar(Port,ONE_SECOND);
  122.                                if((char)Code==XON)
  123.                                    {DisplayLine("XON  received",NULL,0);
  124.                                     lastXchar = XON;
  125.                                     break;
  126.                                    }
  127.                               } /* end -- while */
  128.                          } /* end -- if(XOFF) */
  129.                     } /* end -- if(Code) */
  130.                 } /* end -- if(XON) */
  131.  
  132.           } /* end -- for(i) */
  133.      } /* end -- while */
  134.  close(Handle);
  135.  /* send termination character */
  136.  if(TermChar) PutChar(Port,(char)TermChar);
  137.  DisplayLine("ASCII: Transfer Complete",NULL,0);
  138.  return(TRUE);
  139. } /* end -- TxAcsii */
  140.  
  141. int RxAscii(
  142.   int Port,            /* COM port [0..3] */
  143.   char Filename[],     /* filename buffer */
  144.   char Buffer[],       /* data buffer */
  145.   int Length,          /* length of data buffer */
  146.   int RxQueSize,       /* size of PCL receive buffer */
  147.   int SyncFlag,        /* synchronize with XON 1st */
  148.   int TermChar,        /* termination character (0x00 ==> none) */
  149.   int TimeOut,         /* delay (seconds) before assuming that sender is done */
  150.   int EchoFlag)        /* do local echo if TRUE */
  151. {int i;
  152.  int Handle;         /* file Handle */
  153.  int Code;           /* return code */
  154.  int lo;             /* receive queue low water mark */
  155.  int hi;             /* receive queue high water mark */
  156.  int Index;          /* buffer index */
  157.  int QueSize;        /* current PCL receive queue size */
  158.  int RxChars = 0;    /* # received chars */
  159.  int Count;          /* # characters written to disk */
  160.  char Temp[81];      /* temporary buffer */
  161.  long LastTime;      /* time last character was received */
  162.  /* begin */
  163.  lastXchar = XON;
  164.  lo = RxQueSize / 8;
  165.  hi = 5 * lo;
  166.  DisplayLine("ASCII: Starting receive ",NULL,0);
  167.  while(SioKeyPress()) SioKeyRead();
  168.  /* clear comm port */
  169.  SioRxFlush(Port);
  170.  /* open file passed in Filename[] for write */
  171.  Handle = open(Filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,S_IWRITE);
  172.  if(Handle<0)
  173.      {strcpy(Temp,"Cannot open ");
  174.       strcat(Temp,Filename);
  175.       DisplayLine(Temp,NULL,0);
  176.       return(FALSE);
  177.      }
  178.  /* sync with XON 1st ? */
  179.  if(SyncFlag)
  180.     {DisplayLine("ASCII: Sending initial XON",NULL,0);
  181.      while(1)
  182.         {SioPutc(Port,XON);
  183.          Code = SioGetc(Port,ONE_SECOND);
  184.          if(Code==-1) continue;
  185.          /* transmitter is sending ! */
  186.          SioUnGetc(Port,Code);
  187.          break;
  188.         }
  189.     }
  190.  /* receive text */
  191.  LastTime = SioTimer();
  192.  Index = 0;
  193.  while(1)
  194.      {/* user want to quit ? */
  195.       if(SioBrkKey())
  196.           {DisplayLine("Canceled by USER",NULL,0);
  197.            return(FALSE);
  198.           }
  199.       /* check on PCL receive queue size */
  200.       QueSize = SioRxQue(Port);
  201.       if((QueSize>hi)&&(lastXchar==XON))
  202.           {PutChar(Port,XOFF);
  203.            lastXchar = XOFF;
  204.            DisplayLine("sending XOFF(1)",NULL,0);
  205.            /*printf("\nQueSize=%d lo=%d hi=%d\n",QueSize,lo,hi);*/
  206.           }
  207.       if((QueSize<lo)&&(lastXchar==XOFF))
  208.           {PutChar(Port,XON);
  209.            lastXchar = XON;
  210.            DisplayLine("sending XON ",NULL,0);
  211.           }
  212.       /* User ABORTS ? */
  213.       if(UserAborts(Port)) return(FALSE);
  214.       /* get next byte */
  215.       Code = GetChar(Port,ONE_SECOND);
  216.       if(Code==-1)
  217.          {/* done if having exceeded timeout */
  218.           if(SioTimer()-LastTime>ONE_SECOND*TimeOut)
  219.             {/* sender must be done */
  220.              Buffer[Index] = CTLZ;
  221.              break;
  222.             }
  223.           continue;
  224.          }
  225.       /* ignore 1st character if it is a 0 */
  226.       if((RxChars==0)&&((char)Code=='\0')) continue;
  227.       LastTime = SioTimer();
  228.       /* ignore XON & XOFF ( since we are the receiver ) */
  229.       if((char)Code==XON) continue;
  230.       if((char)Code==XOFF) continue;
  231.       /* received a character */
  232.       Buffer[Index++] = (char)Code;
  233.       RxChars++;
  234.       /* TermChar marks the end of a text file */
  235.       if((char)Code==TermChar)
  236.           {/* replace TermChar with ^Z */
  237.            Buffer[Index-1] = CTLZ;
  238.            RxChars++;
  239.            break;
  240.           }
  241.       if(EchoFlag) MyCrtWrite((char)Code);
  242.       if(Index==Length)
  243.           {/* send XOFF to transmitter */
  244.            PutChar(Port,XOFF);
  245.            lastXchar = XOFF;
  246.            DisplayLine("sending XOFF(2)",NULL,0);
  247.            /* write disk file */
  248.            Count = write(Handle,Buffer,Index);
  249.            if(Count<0)
  250.                {SayError(Port,"Disk read error");
  251.                 SioDelay(ONE_SECOND);
  252.                 return(FALSE);
  253.                }
  254.            /* send XON to sender */
  255.            PutChar(Port,XON);
  256.            lastXchar = XON;
  257.            DisplayLine("sending XON ",NULL,0);
  258.            Index = 0;
  259.           } /* end -- if */
  260.      } /* end -- while */
  261.  /* write any remaining data in buffer */
  262.  if(Index>0)
  263.      {Count = write(Handle,Buffer,Index);
  264.       if(Count<0)
  265.           {SayError(Port,"Disk read error");
  266.            SioDelay(ONE_SECOND);
  267.            return(FALSE);
  268.           }
  269.      } /* end -- if */
  270.  close(Handle);
  271.  DisplayLine("ASCII: Transfer Complete",NULL,0);
  272.  return(TRUE);
  273. } /* RxAscii */
  274.  
  275. int UserAborts(int Port)
  276. {char UserChar;
  277.  /* user aborts ? */
  278.  if(SioKeyPress())
  279.     {UserChar = (char)SioKeyRead();
  280.      if(UserChar==CAN)
  281.        {TxCAN(Port);
  282.         SioPutc(Port,ETX);
  283.         DisplayLine("*** Canceled by USER ***",NULL,0);
  284.         return(TRUE);
  285.        }
  286.      /* send user char */
  287.      SioPutc(Port,UserChar);
  288.     }
  289.  return(FALSE);
  290. } /* UserAborts */